#include "../Logs/Log.h"
#include <unistd.h>
#include <chrono>
// 使用说明--测试同步日志器的输出性能和异步日志器在多线程的情况下的输出性能
void Bench(const std::string &name, int thread_num, size_t Lognums, int loglen)
{
    // 1 获取指定日志器
    std::shared_ptr<MyLogger::Logger> LogPtr = MyLogger::LoggerManager::GerInsrance().GetLogger(name);
    // 2 创建多线程
    std::vector<std::thread> _threads;
    // 构建日志
    std::string Me(loglen - 1, 'G'); // 最后一个位置添加\n
    //Me.push_back('\n');

    // 每个线程写日志的数量
    int thread_Me_num = Lognums / thread_num;
    // 每个线程花的时间
    std::vector<double> t_arry(thread_num);
    // 4 创建线程测试
    for (int i = 0; i < thread_num; i++)
    {
        // 构造线程并且启动，把日志器对象传递进去
        // 多个线程可以用一个日志器对象因为写入操作加锁了
        _threads.emplace_back(
            [&, i]() { // 日志器对象引用捕捉 值捕捉i捕捉到函数内部
                // 线程内部开始计时
                auto start = std::chrono::high_resolution_clock::now();
                for (int j = 0; j < thread_Me_num; j++)
                {
                    LogPtr->Fatal("%s", Me.c_str());
                }
                auto end = std::chrono::high_resolution_clock::now();
                std::chrono::duration<double> tsum = end - start;
                // 记录每个线程耗费时间，不用加锁因为是值捕捉的i，每个线程的i不一样
                t_arry[i] = tsum.count();
                std::cout << "线程：" << i << ":" << "\t输出的日志数量:" << thread_Me_num << " 耗时：" << tsum.count() << "s"<<std::endl;
            });
    }
    for (int i = 0; i < thread_num; i++)
    {
        _threads[i].join(); // 等待线程结束
    }

    //计算总耗时，由于是多线程，所以只用计算多个线程耗时最高的就行了，线程可以看作并发执行的
    double max_time=t_arry[0];
    for(auto t:t_arry)t>max_time?max_time=t:max_time=max_time;

    std::cout<<"日志总数量："<<Lognums<<"\t日志总大小:"<<(Lognums*loglen)/1024.0<<"MB"<<std::endl;
    std::cout<<"总耗时:"<<max_time<<std::endl;

    std::cout<<"每秒钟输出的日志数量"<<(size_t)(Lognums/max_time)<<std::endl;
     std::cout<<"每秒钟输出的日志大小"<<((size_t)((Lognums/max_time)*loglen)/1024)<<"MB"<<std::endl;
}

//同步输出测试
void Sync()
{
    //创建全局的日志器对象，直接从日志器管理对象获取即可
    // std::unique_ptr<MyLogger::LoggerBuilder> Build=std::make_unique<MyLogger::BuildGlobalLogger>("USync");
    // Build->BuildLogger_Limit_Level(LogLevel::Level::DEBUG);
    // Build->BuildLoggerFormater("%m%n");
    // Build->BuildLoggerType(MyLogger::LoggerType::LOGGER_USYNC);
    // Build->BuiltLogLand<LogToFile>("./TestLog/usync.log");
    // Build->Build();
    std::unique_ptr<MyLogger::LoggerBuilder> Buile = std::make_unique<MyLogger::BuildGlobalLogger>("USync");

    Buile->BuildLoggerType(MyLogger::LoggerType::LOGGER_USYNC);
    Buile->BuiltLogLand<LogToFile>("./Usynclog/log1.txt");

    std::shared_ptr<MyLogger::Logger> LogPtr = Buile->Build();
    MyLogger::LoggerManager::GerInsrance().AddLogger(LogPtr);
    Bench("USync",3,1000000,100);
}

int main()
{
    Sync();

}